package com.nova.edc.service.energy.impl;

import com.nova.edc.dao.energy.GatherSummaryDao;
import com.nova.edc.model.energy.Energy;
import com.nova.edc.model.energy.GatherSummary;
import com.nova.edc.model.system.*;
import com.nova.edc.model.util.CountModel;
import com.nova.edc.service.energy.GatherSummaryService;
import com.nova.edc.service.system.DeviceTypeService;
import com.nova.edc.service.system.ElecEnergyService;
import com.nova.frame.dao.parsing.SQLParser;
import com.nova.frame.utils.DateUtils;
import com.nova.frame.utils.JdbcUtils;
import com.nova.module.sql.SqlBuffer;
import com.seio.edc.util.AssitDateUtil;
import com.seio.edc.util.DateTimeUtil;
import com.seio.edc.util.StringUtil;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.math.BigDecimal;
import java.util.*;

/**
 * Created by Administrator on 2016/3/16 0016.
 */
public class GatherSummaryServiceImpl implements GatherSummaryService {


    @Autowired
    private GatherSummaryDao novaGatherSummaryDao;
    @Autowired
    private DeviceTypeService novaDeviceTypeService;
    @Autowired
    private DeviceTypeService novaDeviceTypeServicel;
    @Autowired
    private ElecEnergyService novaElecEnergyService;

    @Override
    public List<GatherSummary> findStateTime(Integer state, String date) {
        String sql = "SELECT " +
                " tg.GatewayID, " +
                " tg.SensorID, " +
                " tg.ChannelID, " +
                " sum(ActiveTime)                  ActiveTime, " +
                " date_format(StartDate, '%Y-%m-%d') SummaryDate, " +
                " PointID, " +
                " tg.AreaId, " +
                " tg.CustomerInfoId, " +
                " ta.Power_1 TraPower, " +
                " ta.Power_2 LedPower, " +
                " ta.RealPower " +
                " FROM t_gather tg LEFT JOIN t_area_point  ta ON ta.ID = tg.PointID " +
                " WHERE ActiveState = ? AND date_format(StartDate, '%Y-%m-%d') = ? " +
                " GROUP BY GatewayID, SensorID, ChannelID " +
                " ORDER BY GatewayID, SensorID, ChannelID ";
        List<GatherSummary> query = JdbcUtils.query(GatherSummary.class, sql, state, date);
        return query;
    }

    @Override
    public void insertList(List<GatherSummary> list) {
        for (GatherSummary gatherSummary : list) {
            novaGatherSummaryDao.insert(gatherSummary);
        }
    }

    @Override
    public double findEnergyByDatePoint(List<AreaPoint> areaPointList, String startDate, String endDate) {
        if (areaPointList != null && areaPointList.size() > 0) {
            String sql = "SELECT sum(cost) sum " +
                    "FROM ( " +
                    " SELECT RealPower * t_gather_summary.ActiveTime / 60000 cost " +
                    " FROM t_gather_summary " +
                    " WHERE SummaryDate >= ? AND SummaryDate <= ? AND PointID IN (#) ) summary;";
            List<Integer> pointId = getPointId(areaPointList);
            String join = StringUtils.join(pointId, ",");
            sql = sql.replace("#", join);
            List<Map<String, Object>> maps = JdbcUtils.queryMap(sql, startDate, endDate);
            if (maps != null && maps.size() > 0) {
                BigDecimal sum = (BigDecimal) maps.get(0).get("sum");
                return sum.doubleValue();
            } else {
                return 0;
            }
        } else {
            return 0;
        }

    }


    public List<Integer> getPointId(List<AreaPoint> areaPointList) {
        ArrayList<Integer> list = new ArrayList<Integer>();
        for (AreaPoint areaPoint : areaPointList) {
            list.add(areaPoint.getId());
        }
        return list;
    }

    @Override
    public List<Map<String, Object>> getCostbydevice(int customerInfoId,
                                                     String startDate, String endDate) {
        SqlBuffer sqlBuffer = new SqlBuffer(
                SQLParser.sql("gatherSummarySQL.getCostbydevice"), true);
        DeviceType light = novaDeviceTypeService.getByName(ModelConstant.DEVICE_LIGHTENERGY);
        DeviceType air = novaDeviceTypeService.getByName(ModelConstant.DEVICE_AIR);
        List<Map<String, Object>> result = JdbcUtils.queryMap(
                sqlBuffer.getSelectSql(), light.getId(), air.getId(), startDate, endDate, customerInfoId);
        return result;
    }

    @Override
    public List<Map<String, Object>> findAllEnergy(String area, Integer searchTimeType) {
        String addsql = "";
        if (area != null && area != "") {
            addsql = " AND (t_customerinfo.Province = '" + area + "' or t_customerinfo.City= '" + area + "'  or t_customerinfo.District= '" + area + "' )";
        }
        addsql = addsql + getSearchSql(searchTimeType);
        String sql = "SELECT " +
                "  t_device_type.Name Devie, " +
                "  sum(t_gather_summary.ActiveTime * t_gather_summary.RealPower / 60000) Energy " +
                "FROM t_gather_summary " +
                "  LEFT JOIN t_area_point ON t_gather_summary.PointID = t_area_point.ID " +
                "  LEFT JOIN t_device_type ON t_area_point.DeviceTypeId = t_device_type.ID " +
                " LEFT JOIN t_customerinfo ON t_gather_summary.CustomerInfoId = t_customerinfo.ID " +
                " WHERE t_device_type.Name IN ('空调', '灯具') AND t_area_point.DeviceTypeId IS NOT NULL " + addsql +
                " GROUP BY t_area_point.DeviceTypeId,t_device_type.Name ";
        List<Map<String, Object>> query = JdbcUtils.queryMap(sql);
        return query;
    }

    public String getSearchSql(Integer type) {
        String addsql = "";
        switch (type) {
            case 0:
                addsql = " AND date_format(t_gather_summary.SummaryDate,'%Y-%m')= '" + DateUtils.getDate2Str("YYYY-MM", AssitDateUtil.getAddMonth(new Date(), -2)) + "'";
                break;
            case 1:
                addsql = " AND date_format(t_gather_summary.SummaryDate,'%Y-%m')= '" + DateUtils.getDate2Str("YYYY-MM", AssitDateUtil.getAddMonth(new Date(), -1)) + "'";
                break;
            case 2:
                addsql = " AND date_format(t_gather_summary.SummaryDate,'%Y-%m-%d')= '" + DateUtils.getDate2Str("YYYY-MM-dd", DateUtils.getYesterdayDate()) + "'";
                break;
            case 3:
                addsql = " AND date_format(t_gather_summary.SummaryDate,'%Y-%m')= '" + DateUtils.getDate2Str("YYYY-MM", AssitDateUtil.getAddMonth(new Date(), -1)) + "'";
                break;
            case 4:
                addsql = " AND date_format(t_gather_summary.SummaryDate,'%Y')= '" + DateTimeUtil.getNowTime("YYYY") + "'";
                break;
            case 5:
                addsql = " AND date_format(t_gather_summary.SummaryDate,'%Y')= '" + DateUtils.getDate2Str("YYYY", AssitDateUtil.getAddMonth(new Date(), -12)) + "'";
                break;
            case 6:
                addsql = "";
                break;
            default:
                addsql = " AND date_format(t_gather_summary.SummaryDate,'%Y-%m')= '" + DateTimeUtil.getNowTime("YYYY-MM") + "'";
        }
        return addsql;
    }

    @Override
    public List<Map<String, Object>> getEnergyByRegion(int customerinfoId,
                                                       String startDate, String endDate) {
        SqlBuffer sqlBuffer = new SqlBuffer(
                SQLParser.sql("gatherSummarySQL.getPowerByRegion"), true);
        List<Map<String, Object>> result = JdbcUtils.queryMap(
                sqlBuffer.getSelectSql(), customerinfoId, startDate, endDate);
        return result;
    }

    @Override
    public List<Map<String, Object>> getAllEnergyByDate(int customerinfoId, String startDate, String endDate, int deviceId) {
        SqlBuffer sqlBuffer = new SqlBuffer(
                SQLParser.sql("gatherSummarySQL.getAllPowerByDate"), true);
        List<Map<String, Object>> result = JdbcUtils.queryMap(
                sqlBuffer.getSelectSql(), customerinfoId, startDate, endDate, deviceId);

        return result;
    }

    @Override
    public List<Map<String, Object>> getUnitEnergyByDate(String customerinfoId,
                                                         String startDate, String endDate) {
        SqlBuffer sqlBuffer = new SqlBuffer(
                SQLParser.sql("gatherSummarySQL.getUnitEnergyByDate"), true);
        List<Map<String, Object>> result = JdbcUtils.queryMap(sqlBuffer
                .getSelectSql().replace("#", customerinfoId), startDate, endDate);
        return result;

    }

    @Override
    public List<Map<String, Object>> getEnergyByDate(int customerinfoId,
                                                     String startDate, String endDate) {
        SqlBuffer sqlBuffer = new SqlBuffer(
                SQLParser.sql("gatherSummarySQL.getPowerByDate"), true);
        List<Map<String, Object>> result = JdbcUtils.queryMap(
                sqlBuffer.getSelectSql(), customerinfoId, startDate, endDate);
        return result;
    }

    @Override
    public List<Map<String, Object>> getStatisticsByDayCuscomer(CountModel countModel, List<CustomerInfo> customerInfoList) {
        if (customerInfoList != null && customerInfoList.size() > 0) {
            SqlBuffer sqlBuffer = new SqlBuffer(
                    SQLParser.sql("gatherSummarySQL.getStatisticsByDayCuscomer"), true);
            List<Integer> customerinfoId = new ArrayList<Integer>();
            for (int i = 0; i < customerInfoList.size(); i++) {
                customerinfoId.add(customerInfoList.get(i).getId());
            }
            DeviceType lightDevice = novaDeviceTypeServicel.getByName(ModelConstant.DEVICE_LIGHTENERGY);
            DeviceType airDevice = novaDeviceTypeServicel.getByName(ModelConstant.DEVICE_AIR);
            List<Map<String, Object>> maps = JdbcUtils.queryMap(sqlBuffer.getSelectSql().replace("#",
                    org.apache.commons.lang3.StringUtils.join(customerinfoId, ",")), lightDevice.getId(), airDevice.getId(), countModel.getStartDate(), countModel.getEndDate());
            return maps;
        } else {
            return null;
        }
    }

    @Override
    public int positionInProvince(CustomerInfo customerInfo, String startTime, String endTime) {
        SqlBuffer sqlBuffer = new SqlBuffer(
                SQLParser.sql("gatherSummarySQL.positionInProvince"), true);
        List<Map<String, Object>> maps = JdbcUtils.queryMap(sqlBuffer.getSql(), startTime, endTime,
                "%" + (customerInfo.getProvince() == null ? "" : customerInfo.getProvince()) + "%", customerInfo.getId());
        if (maps != null && maps.size() > 0) {
            double rownum = new Double(maps.get(0).get("rownum").toString());
            return (int) rownum;
        } else {
            return 0;
        }
    }

    @Override
    public List<Map<String, Object>> getGatewayDetail(String searchDate, String gatewayId) {
        SqlBuffer sqlBuffer = new SqlBuffer(
                SQLParser.sql("gatherSummarySQL.getGatewayDetail"), true);
        List<Map<String, Object>> result = JdbcUtils.queryMap(
                sqlBuffer.getSelectSql(), gatewayId, searchDate);
        return result;
    }


    @Override
    public Map<String, BigDecimal> getStatisticsByDate(Integer customerinfoId,
                                                       String startDate, String endDate) {
        SqlBuffer sqlBuffer = new SqlBuffer(
                SQLParser.sql("gatherSummarySQL.getStatisticsByDate"), true);
        List<Map<String, Object>> result = JdbcUtils.queryMap(
                sqlBuffer.getSelectSql().replace("#", customerinfoId.toString()), startDate, endDate);
        BigDecimal savePower = (BigDecimal) result.get(0).get(
                ModelConstant.SAVE_POWER);
        savePower = savePower == null ? BigDecimal.ZERO : savePower;
        BigDecimal saveCost = (BigDecimal) result.get(0).get(
                ModelConstant.SAVE_COST);
        saveCost = saveCost == null ? BigDecimal.ZERO : saveCost;
        Map<String, BigDecimal> map = new HashMap<String, BigDecimal>();

        map.put(ModelConstant.SAVE_POWER, savePower);
        map.put(ModelConstant.SAVE_COST, saveCost);
        return map;

    }

    @Override
    public Map<String, BigDecimal> getAllStatistics(List<Integer> customerInfoIds, String startDate, String endDate) {
        if (customerInfoIds == null || customerInfoIds.size() == 0) {
            customerInfoIds.add(0);
        }
        SqlBuffer sqlBuffer = new SqlBuffer(
                SQLParser.sql("gatherSummarySQL.getStatisticsByDate"), true);
        List<Map<String, Object>> result = JdbcUtils.queryMap(sqlBuffer
                .getSelectSql().replace("#",
                        org.apache.commons.lang3.StringUtils.join(customerInfoIds, ",")), startDate, endDate);
        BigDecimal savePower = (BigDecimal) result.get(0).get(
                ModelConstant.SAVE_POWER);
        savePower = savePower == null ? BigDecimal.ZERO : savePower;
        BigDecimal saveCost = (BigDecimal) result.get(0).get(
                ModelConstant.SAVE_COST);
        saveCost = saveCost == null ? BigDecimal.ZERO : saveCost;
        Map<String, BigDecimal> map = new HashMap<String, BigDecimal>();
        ElecEnergy elecEnergy = novaElecEnergyService
                .findByPowerCode(ModelConstant.SOCIAL_CO2);
        map.put(ModelConstant.SAVE_POWER, savePower);
        map.put(ModelConstant.SAVE_COST, saveCost);
        BigDecimal co2 = savePower.multiply(
                new BigDecimal(elecEnergy.getPowerstandardvalue())).divide(
                new BigDecimal(ModelConstant.SOCAIL_DIVIDE), 2);
        BigDecimal car = co2.divide(new BigDecimal(ModelConstant.SOCAIL_CAR),
                0, BigDecimal.ROUND_HALF_DOWN);
        map.put(ModelConstant.INDEX_CO2, co2);
        map.put(ModelConstant.INDEX_CAR, car);

        return map;
    }

    @Override
    public Map<String, BigDecimal> getUnitStatistics(List<Integer> customerInfoIds, String startDate, String endDate) {
        SqlBuffer sqlBuffer = new SqlBuffer(
                SQLParser.sql("gatherSummarySQL.getUnitStatistics"), true);
        List<Map<String, Object>> result = JdbcUtils.queryMap(
                sqlBuffer.getSelectSql().replace("#", org.apache.commons.lang3.StringUtils.join(customerInfoIds, ",")), startDate, endDate);
        Map<String, BigDecimal> map = new HashMap<String, BigDecimal>();
        if (result.size() > 0) {
            Map<String, Object> resultMap = result.get(0);
            map.put(ModelConstant.UNIT_SAVE_POWER,
                    (BigDecimal) resultMap.get(ModelConstant.UNIT_SAVE_POWER));
            map.put(ModelConstant.UNIT_SAVE_COST,
                    (BigDecimal) resultMap.get(ModelConstant.UNIT_SAVE_COST));
        }
        return map;
    }

    @Override
    public Energy getEnergyByCompany(int customerInfoId, String startDate,
                                     String endDate) {
        SqlBuffer sqlBuffer = new SqlBuffer(
                SQLParser.sql("gatherSummarySQL.getEnergyByCompany"), true);
        Energy energy = JdbcUtils.get(Energy.class, sqlBuffer.getSql().replace("#", String.valueOf(customerInfoId)), startDate, endDate);
        return energy;
    }

    @Override
    public List<Map<String, Object>> getByMapArea(String position, int timeType) {
        SqlBuffer sqlBuffer = new SqlBuffer(SQLParser.sql("gatherSummarySQL.getByMapArea"), true);
        List<Map<String, Object>> query = JdbcUtils.queryMap(sqlBuffer.getSelectSql()
                .replace("#", "'" + ModelConstant.DEVICE_LIGHTENERGY + "','" + ModelConstant.DEVICE_AIR + "'")
                .replace("&", "'" + position + "'")
                .replace("$", getSearchSql(timeType)));
        return query;
    }

    @Override
    public List<Map<String, Object>> getEnergyByCompanyAPI(List<CustomerInfo> customerInfoList, String startDate, String endDate, String format) {
        if (customerInfoList != null && customerInfoList.size() > 0) {
            SqlBuffer sqlBuffer = new SqlBuffer(
                    SQLParser.sql("gatherSummarySQL.getEnergyByCompanyAPI"), true);
            List<Integer> customerinfoId = new ArrayList<Integer>();
            for (int i = 0; i < customerInfoList.size(); i++) {
                customerinfoId.add(customerInfoList.get(i).getId());
            }
            DeviceType lightDevice = novaDeviceTypeServicel.getByName(ModelConstant.DEVICE_LIGHTENERGY);
            DeviceType airDevice = novaDeviceTypeServicel.getByName(ModelConstant.DEVICE_AIR);
            List<Map<String, Object>> maps = JdbcUtils.queryMap(sqlBuffer.getSelectSql().replace("#",
                    org.apache.commons.lang3.StringUtils.join(customerinfoId, ",")).replace("$", format), lightDevice.getId(), airDevice.getId(), startDate, endDate);
            return maps;
        } else {
            return null;
        }
    }

    @Override
    public List<Map<String, Object>> getEnergyByAreaAPI(List<CustomerInfo> customerInfoList, String startDate, String endDate, String areaType, int orderType) {
        if (customerInfoList != null && customerInfoList.size() > 0) {
            SqlBuffer sqlBuffer = new SqlBuffer(
                    SQLParser.sql("gatherSummarySQL.getEnergyByAreaAPI"), true);
            if (ModelConstant.API_ORDERTYPE_UNITPERSON == orderType) {
                sqlBuffer.appendOrder(ModelConstant.API_ORDER_UNITPERSON, "desc");
            } else if (ModelConstant.API_ORDERTYPE_UNITSQUARE == orderType) {
                sqlBuffer.appendOrder(ModelConstant.API_ORDER_UNITSQUARE, "desc");
            } else {
                sqlBuffer.appendOrder(ModelConstant.API_ORDER_POWER, "desc");
            }
            List<Integer> customerinfoId = new ArrayList<Integer>();
            for (int i = 0; i < customerInfoList.size(); i++) {
                customerinfoId.add(customerInfoList.get(i).getId());
            }
            List<Map<String, Object>> maps = JdbcUtils.queryMap(sqlBuffer.getSelectSql().replace("#",
                    org.apache.commons.lang3.StringUtils.join(customerinfoId, ",")).replace("$", areaType), startDate, endDate);
            return maps;
        } else {
            return null;
        }
    }
}
